import paramiko
import subprocess
import platform
from datetime import datetime, timedelta
import ctypes
import sys
from common.logger import logger


class SystemTimeManager:
    def __init__(self, host, port, username, password):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.system = platform.system()

    def is_admin(self):
        if self.system == "Windows":
            try:
                return ctypes.windll.shell32.IsUserAnAdmin()
            except:
                return False
        return True

    def get_linux_server_time(self):
        """
        从 Windows 系统通过 SSH 连接到 Linux 服务器并获取服务器时间戳
        :return: Linux 服务器的时间戳，如果出现错误则返回 None
        """
        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(hostname=self.host, port=self.port, username=self.username, password=self.password)
            stdin, stdout, stderr = ssh.exec_command('date +%s')
            result = stdout.read().decode().strip()
            ssh.close()
            return int(result)
        except paramiko.AuthenticationException:
            logger.error("认证失败，请检查用户名和密码。")
        except paramiko.SSHException as ssh_ex:
            logger.error(f"SSH 连接出现错误: {ssh_ex}")
        except Exception as ex:
            logger.error(f"发生未知错误: {ex}")
        return None

    def get_delayed_time(self, timestamp, delay_seconds):
        """
        根据给定的时间戳和延迟时长（秒），计算延迟后的时间
        :param timestamp: 起始时间戳（秒）
        :param delay_seconds: 延迟的时长（秒），可以为负数或 0
        :return: 延迟后的时间戳（秒）
        """
        original_time = datetime.fromtimestamp(timestamp)
        delayed_time = original_time + timedelta(seconds=delay_seconds)
        return delayed_time.timestamp()

    def set_windows_time(self, target_time):
        """
        修改 Windows 系统的本地时间为指定时间
        :param target_time: 指定的时间，格式为 datetime 对象
        """
        if not self.is_admin():
            logger.error("请以管理员身份运行此脚本，以便修改 Windows 系统时间。")
            return
        date_str = target_time.strftime("%Y-%m-%d")
        time_str = target_time.strftime("%H:%M:%S")
        try:
            subprocess.run(f'date {date_str}', shell=True, check=True)
            subprocess.run(f'time {time_str}', shell=True, check=True)
            logger.info(f"Windows 系统时间已成功设置为: {target_time}")
        except subprocess.CalledProcessError as e:
            logger.error(f"设置 Windows 系统时间时出错: {e}")

    def set_linux_time(self, target_time):
        """
        修改 Linux 服务器的时间为指定时间
        :param target_time: 指定的时间，格式为 datetime 对象
        """
        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(hostname=self.host, port=self.port, username=self.username, password=self.password)
            time_str = target_time.strftime("%Y-%m-%d %H:%M:%S")
            command = f"sudo date -s '{time_str}'"
            stdin, stdout, stderr = ssh.exec_command(command)
            error = stderr.read().decode().strip()
            if error:
                logger.error(f"设置 Linux 系统时间时出错: {error}")
            else:
                logger.info(f"Linux 系统时间已成功设置为: {target_time}")
            ssh.close()
        except paramiko.AuthenticationException:
            logger.error("认证失败，请检查用户名和密码。")
        except paramiko.SSHException as ssh_ex:
            logger.error(f"SSH 连接出现错误: {ssh_ex}")
        except Exception as ex:
            logger.error(f"发生未知错误: {ex}")

    def manage_time(self, delay_seconds=0, set_local=False):
        """
        管理时间的主方法，可获取延迟时间并根据需要设置本地系统时间
        :param delay_seconds: 延迟的时长（秒），可以为负数或 0
        :param set_local: 是否设置本地系统时间
        """
        server_timestamp = self.get_linux_server_time()
        if server_timestamp is not None:
            delayed_timestamp = self.get_delayed_time(server_timestamp, delay_seconds)
            delayed_datetime = datetime.fromtimestamp(delayed_timestamp)
            if set_local:
                if self.system == "Windows":
                    self.set_windows_time(delayed_datetime)
                elif self.system == "Linux":
                    self.set_linux_time(delayed_datetime)
                else:
                    logger.error(f"不支持的操作系统: {self.system}")


if __name__ == "__main__":
    # 配置 Linux 服务器信息
    host = "192.168.31.20"
    port = 22
    username = "root"
    password = "9854353065"

    manager = SystemTimeManager(host, port, username, password)
    # 设置延迟时长（例如延迟 3600 秒，即 1 小时；也可以设为 0 不延迟）
    delay = 3600
    # 根据需要设置是否修改本地系统时间
    manager.manage_time(delay_seconds=delay, set_local=True)